/**
 * Wrapper class for the google geocoding service.
 * 
 * @author Kim Pommert
 * @version %I%, %G%
 */
qx.Class.define("qooxdoosample.google.maps.GGeoCoder",
{
	extend: qx.core.Object,
	implement: qooxdoosample.cocktail.maps.IGeoCoder,
	

	/**
	 * Class constructor.
	 * Instantiates an object of that class.
	 */
	construct: function()
	{
		this.base(arguments);
		this.setGGeocoder(new GClientGeocoder());
    },
    
    properties:
    {
    	/**
    	 * Googles geocoding object.
    	 * All method calls will be converted and sent to this object.
    	 */
    	gGeocoder:
    	{
    		nullable: true,
    		init: null,
    		check: "GClientGeocoder"
    	}
    },
    
    members:
    {
    	/**
    	 * Get the geographic coordinates of the address.
    	 * 
		 * @param address 	{String} The address for geocoding
		 * @param callback 	{Function} The result of the geocoding will be sent to this function
		 * @see qooxdoosample.cocktail.maps.IGeoCoder#getLatLng()
    	 */
    	getLatLng: function(address, callback)
    	{
    		this.getGGeocoder().getLatLng(address, function(point){
    			var res = null; 
    			// address found
    			// convert datatype of result to LatLng and send to callback function
    			if (point) 
	        		res = new qooxdoosample.cocktail.util.LatLng(point.lat(), point.lng());
      			callback(res);
    		});
    	},
    	
    	/**
		 * Get the coordinates and additional information about a specific address
		 * 
		 * @param address	{String} The address for geocoding
		 * @param callback	{Function} The result of the geocoding will be sent to this function
		 * @see qooxdoosample.cocktail.maps.IGeoCoder#getLocationInfo()
		 */
		getLocationInfo: function(address, callback)
		{
			this.getGGeocoder().getLocations(address,  function(response){
    			
    			var res = new qooxdoosample.cocktail.util.Address();
    			
    			if(!response)
    			{
    				alert("Error in request! Response is null.");
    				return null;
    			} 
    			else if(response.Status.code == 610){
    				alert("Error in request! Google Maps API Key is incorrect.");
    				return null;
    			}
    			else if(response.Status.code != 200){
    				alert("Error on Google Geocoding-Service! Status code: " + response.Status.code);
    				return null;
    			}
    			else
    			{
    				var place = response.Placemark[0];
    				
    				/*
    				 * the whole result object has to be checked recursively.
    				 * Every data that is set will be transported to
    				 * the Address object
    				 */
    				
    				var country = place.AddressDetails.Country;
    				
    				var adminArea = false;
    				if(country)
    					adminArea = place.AddressDetails.Country.AdministrativeArea;
    				
    				var subadminArea = false;
    				if(adminArea) 
    				 subadminArea = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea;

    				var locality = false;
    				if(subadminArea) 
    					locality = place.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality;
    				

    				if(place.address)
    					res.setAddress(place.address);
    				if(country){
    					if(country.CountryNameCode)
    						res.setCountry(country.CountryNameCode);
						if(adminArea){
							if(adminArea.AdministrativeAreaName)
    							res.setAdministrativeArea(adminArea.AdministrativeAreaName);
    						if(subadminArea){
    							if(subadminArea.SubAdministrativeAreaName)
    								res.setSubAdministrativeArea(subadminArea.SubAdministrativeAreaName);
    							if(locality){
    								if(locality.LocalityName)
    									res.setLocality(locality.LocalityName);
    								if(locality.Thoroughfare && locality.Thoroughfare.ThoroughfareName)
    									res.setThoroughfare(locality.Thoroughfare.ThoroughfareName);
    								if(locality.PostalCode && locality.PostalCode.PostalCodeNumber)
    									res.setPostalCode(locality.PostalCode.PostalCodeNumber);    								
    							}
    							
    						}
						}
    				}
    				
    				var lat = place.Point.coordinates[1];
    				var lng = place.Point.coordinates[0];
    				var coord = new qooxdoosample.cocktail.util.LatLng(lat, lng);
    				
    				res.setCoordinates(coord);
    			}
      			callback(res);
    		});
		},
			
		/**
		 * Perform reversed geocoding. 
		 * This will get the address of a specific geographical coordinate.
		 * 
		 * @param latlng	{qooxdoosample.cocktail.util.LatLng} The coordinate for reversed geocoding
		 * @param callback	{Function} The result of the reversed geocoding will be sent to this function
		 * @see qooxdoosample.cocktail.maps.IGeoCoder#getAddress()
		 */
		getAddress: function(latlng, callback)
		{
			var gLatLng = new GLatLng(latlng.getLatitude(), latlng.getLongitude());
			
			// google uses the same method for reverse geocoding
			// -> call the getLocationInfo function using the GLatLng object as input parameter
			this.getLocationInfo(gLatLng, callback);
		}
    }
});